home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 6
/
CU Amiga Magazine's Super CD-ROM 06 (1996)(EMAP Images)(GB)(Track 1 of 4)[!][issue 1997-01].iso
/
cucd
/
online
/
fidonetts
/
3csrc.lzh
/
3to2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-12
|
10KB
|
390 lines
/*
* type 3 ASCII to type 2 packet converter
* Public Domain
*
* command line arguments: <name-of-type-3-ASCII-pkt> <name-of-type-2-pkt>
*
* this needs heavier error checking and some prettying up before it
* "real" use...should do in a pinch, though.
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
#include "3mail.h"
struct address {
unsigned int
zone,net,node,point;
char domain[9];
};
struct privdata {
int handle;
char *fname;
struct address me;
struct address from;
struct address to;
};
/* Packet header structure per FSC-0045 */
struct pkthdr2 {
unsigned int
onode,
dnode,
opoint,
dpoint;
char
zeros[8];
unsigned int
subver,
version,
onet,
dnet;
char
product,
rev_lev,
password[8];
unsigned int
ozone,
dzone;
char
odomain[8],
ddomain[8];
long
specific;
};
extern int parse_addr3 (char *addr3,struct address *addr); /* 3supp.c */
extern char * type3a_2_fido (char *a,int sea); /* 3supp.c */
int import_3msg (void *priv,PHDR3 *pkt3,MHDR3 *msg3,char *text,
int textlen,int *error) {
/* this function is called to import/forward the message
* in this case, it writes a header and message text to
* a type 2 packet.
*/
struct privdata *pd;
char pmsg[192],*p,*pp;
unsigned int x;
struct address addr;
TAG3 *info;
long pos;
static long nummsgs = 0L;
pd = (struct privdata *)priv;
if((!msg3->to && !msg3->area && !pkt3->area) || !msg3->date ||
!msg3->from || !msg3->id) {
*error = BADPKTHDR3;
return *error;
}
*error = NOERR3;
memset (pmsg, 0, 192);
*pmsg = 0x02;
pmsg[1] = 0x00;
if(!parse_addr3(msg3->from,&addr)) {
memcpy (&pmsg[2], &addr.node, 2);
memcpy (&pmsg[6], &addr.net, 2);
}
else {
memcpy (&pmsg[2], &pd->from.node, 2);
memcpy (&pmsg[6], &pd->from.net, 2);
}
if(!parse_addr3(msg3->to,&addr)) {
memcpy (&pmsg[4], &addr.node, 2);
memcpy (&pmsg[8], &addr.net, 2);
}
else {
memcpy (&pmsg[4], &pd->to.node, 2);
memcpy (&pmsg[8], &pd->to.net, 2);
}
x = 0;
info = msg3->head;
while(info) {
if(info->tag && !stricmp(info->tag,"PRIV")) {
x |= 1;
break;
}
info = info->next;
}
memcpy (&pmsg[10], &x, 2);
x = 0;
memcpy (&pmsg[12], &x, 2);
pp = type3a_2_fido (msg3->date,1);
memcpy (&pmsg[14], pp, 20);
p = &pmsg[34];
if(msg3->to && *msg3->to != '@' && (pp = strchr(msg3->to,'@')) != NULL) {
strncpy(p,msg3->to,min(35,(int)pp - (int)msg3->to));
}
else strcpy(p,"All");
x = 34;
while (*p) {
x++;
p++;
}
p++;
x++;
if(msg3->from && *msg3->from != '@' && (pp = strchr(msg3->from,'@')) != NULL) {
strncpy (p, msg3->from, min(35,(int)pp - (int)msg3->from));
}
else strcpy(p,"Sysop");
while (*p) {
x++;
p++;
}
x++;
p++;
if(msg3->subj) {
strncpy(p,msg3->subj,71);
}
while (*p) {
x++;
p++;
}
x++;
p++;
write (pd->handle, pmsg, x);
if(pkt3->area) {
write(pd->handle,"AREA:",5);
write(pd->handle,pkt3->area,strlen(pkt3->area));
write(pd->handle,"\r",1);
}
else if(msg3->area) {
write(pd->handle,"AREA:",5);
write(pd->handle,msg3->area,strlen(msg3->area));
write(pd->handle,"\r",1);
}
write(pd->handle,"\01MSGID: ",8);
if(*msg3->id != ' ') write(pd->handle,msg3->id,strlen(msg3->id));
else {
pp = strchr(msg3->from,'@');
if(pp) pp++;
else pp = msg3->from;
write(pd->handle,pp,strlen(pp));
write(pd->handle,msg3->id,strlen(msg3->id));
}
write(pd->handle,"\r",1);
if(msg3->ref) {
write(pd->handle,"\01REPLY: ",8);
write(pd->handle,msg3->ref,strlen(msg3->ref));
write(pd->handle,"\r",1);
}
info = msg3->head;
while(info) {
if(info->tag) {
write(pd->handle,"\01",1);
write(pd->handle,info->tag,strlen(info->tag));
}
else if(info->data) write(pd->handle,"\01NOTAG",6);
if(info->data) {
write(pd->handle,":",1);
write(pd->handle,info->data,strlen(info->data));
}
if(info->tag || info->data) write(pd->handle,"\r",1);
info = info->next;
}
write(pd->handle,text,textlen - 1);
write(pd->handle,"\0\0",3);
pos = tell(pd->handle);
if(pos) lseek(pd->handle,pos - 2L,SEEK_SET);
printf("%ld\r",++nummsgs);
return 0;
}
int appendin_3msg (void *priv,PHDR3 *phdr,MHDR3 *mhdr,char *text,
int textlen,int *error) {
/* this function is called if more than one pass at the message
* text is required. in this case, it appends the message text
* to the type 2 packet being created.
*/
struct privdata *pd;
long pos;
*error = NOERR3;
pd = (struct privdata *)priv;
pos = tell(pd->handle);
if(pos) lseek(pd->handle,pos - 1L,SEEK_SET);
write(pd->handle,text,textlen - 1);
write(pd->handle,"\0\0",3);
pos = tell(pd->handle);
if(pos) lseek(pd->handle,pos - 2L,SEEK_SET);
return 0;
}
int check_3pkthdr (void *priv,char *fname,PHDR3 *pkt3,int *error) {
/* this "callback" function should check packet header and decide
* if you want to process the packet. return 0 if so, anything
* else if not. in this case it creates the type 2 packet and
* writes its header. Note that data may be lost from the 3a pkt
* header to the 2 pkt header as there's no provision in 2 pkts for
* something like kludge lines...
*/
struct privdata *pd;
struct pkthdr2 pkt2;
struct address addr;
long pos;
*error = NOERR3;
pd = (struct privdata *)priv;
unlink(pd->fname);
pd->handle = sopen(pd->fname,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE | S_IREAD);
if(pd->handle != -1) {
memset(&pkt2,0,sizeof(struct pkthdr2));
pkt2.version = 2;
pkt2.subver = 2;
if(pkt3->pword) strncpy(pkt2.password,pkt3->pword,8);
if(!parse_addr3(pkt3->from,&addr)) {
memcpy(&pd->from,&addr,sizeof(struct address));
pkt2.ozone = addr.zone;
pkt2.onet = addr.net;
pkt2.onode = addr.node;
strncpy(pkt2.odomain,addr.domain,8);
if(pkt3->to) {
if(parse_addr3(pkt3->to,&addr)) {
printf("\nTo: field grunged; bad packet\n");
*error = BADPKTHDR3;
return *error;
}
}
else memcpy(&addr,&pd->me,sizeof(struct address));
memcpy(&pd->to,&addr,sizeof(struct address));
pkt2.dzone = addr.zone;
pkt2.dnet = addr.net;
pkt2.dnode = addr.node;
pkt2.dpoint = addr.point;
strncpy(pkt2.ddomain,addr.domain,8);
write(pd->handle,&pkt2,sizeof(struct pkthdr2));
write(pd->handle,"\0\0",3);
pos = tell(pd->handle);
if(pos) lseek(pd->handle,pos - 3L,SEEK_SET);
}
else *error = BADPKTHDR3;
}
else {
*error = NOOPEN3;
printf("\nOpen of %s failed.\n",pd->fname);
}
return *error;
}
int check_3msghdr (void *priv,MHDR3 *msg3,int *error) {
/* this "callback" function should check message header and decide
* if you want to process the message. return 0 if so, anything
* else if not. this one doesn't do anything...
*/
*error = NOERR3;
return 0;
}
void end_3msg (void *priv,PHDR3 *pkt3,MHDR3 *msg3) {
/* make tiny seenbys to keep old type 2s from choking */
struct privdata *pd;
long pos;
char seenby[81];
struct address addr;
if(!pkt3->area && !msg3->area) return;
pd = (struct privdata *)priv;
pos = tell(pd->handle);
if(pos) lseek(pd->handle,pos - 1L,SEEK_SET);
strcpy(seenby,"\rSEEN-BY");
if(!parse_addr3(msg3->from,&addr)) {
sprintf(&seenby[strlen(seenby)]," %u/%u",addr.net,addr.node);
if(addr.net != pd->from.net || addr.node != pd->from.node) {
sprintf(&seenby[strlen(seenby)]," %u/%u",pd->from.net,pd->from.node);
}
}
else {
sprintf(&seenby[strlen(seenby)]," %u/%u",pd->from.net,pd->from.node);
}
if(!parse_addr3(msg3->to,&addr)) {
sprintf(&seenby[strlen(seenby)]," %u/%u",addr.net,addr.node);
if(addr.net != pd->to.net || addr.node != pd->to.node) {
sprintf(&seenby[strlen(seenby)]," %u/%u",pd->to.net,pd->to.node);
}
if((pd->to.net != pd->me.net || pd->to.node != pd->me.node) &&
(addr.net != pd->me.net || addr.node != pd->me.node)) {
sprintf(&seenby[strlen(seenby)]," %u/%u",pd->me.net,pd->me.node);
}
}
else {
sprintf(&seenby[strlen(seenby)]," %u/%u",pd->to.net,pd->to.node);
if(pd->to.net != pd->me.net || pd->to.node != pd->me.node) {
sprintf(&seenby[strlen(seenby)]," %u/%u",pd->me.net,pd->me.node);
}
}
strcat(seenby,"\r");
write(pd->handle,seenby,strlen(seenby));
write(pd->handle,"\0\0",3);
pos = tell(pd->handle);
if(pos) lseek(pd->handle,pos - 2L,SEEK_SET);
return;
}
int main (int argc,char *argv[]) {
int error;
struct privdata pd;
if(argc < 4) {
printf("\n\n3to2 packet converter\n"
"Converts type 3 ASCII packets to type 2\n"
"\nUsage: 3to2 <type3Apacket> <type2packet> <to_address>\n"
"\n<to_address> format: Domain#Zone:Net/Node.Point\n\n");
return -1;
}
memset(&pd,0,sizeof(struct privdata));
pd.handle = -1;
pd.fname = argv[2];
if(parse_addr3(argv[3],&pd.me)) {
printf("\nError in <to_address> \"%s\"\n",argv[3]);
return -1;
}
printf("\n3to2 packet converter\n%s -=> %s\n",argv[1],argv[2]);
printf("\n\n ** Converted %ld msgs\n",
process_3pkt((void *)&pd,argv[1],&error));
if(error && error != EOP3)
error3a(error);
if(pd.handle != -1) close(pd.handle);
return error;
}